type RetryOptions = {
    maxRetries?:number,
    delay?:number,
}
type MethodType = 'GET'|'POST'|'PUT'|'DELETE';

type RequestOptions = {
    method:MethodType,
    headers?:any,
    body?:any, 
}

const sleep = (ms:number) => {
    const start = Date.now();
    while (Date.now() - start < ms) {}
}

/**
 * 重试请求函数，用于发送带有重试机制的请求。
 * @param {string} url - 请求的URL。
 * @param {RetryOptions} [retryOptions] - 重试选项，包含最大重试次数和重试延迟时间。
 * @param retryOptions.maxRetries {number} - 最大重试次数，默认为3。
 * @param retryOptions.delay {number} - 重试延迟时间，单位为毫秒，默认为100毫秒。
 * @param {RequestOptions} [requestOptions] - 请求选项，包含请求方法、请求头和请求体。
 * @param requestOptions.method {MethodType} - 请求方法，可选值为'GET'、'POST'、'PUT'或'DELETE'。
 * @param requestOptions.headers {Record} - 请求头，以键值对的形式表示。
 * @param requestOptions.body {any} - 请求体，可选。
 * @returns {Promise} - 返回一个Promise，解析为请求的响应数据或拒绝为错误信息。
 */
export function retryRequest(url:string,retryOptions?:RetryOptions,requestOptions?:RequestOptions):Promise<any>{
    const {maxRetries=3,delay=100} = retryOptions||{};
    return fetch(url,requestOptions)
    .then(async (res) => {
        if (res.status === 200) {
            return Promise.resolve(await res.json());
        }else {
            try {
                // 解析成功，将错误信息作为Promise的拒绝值返回
                return Promise.reject(await res.json());
            } catch (error) {
                // 如果解析失败，从响应中提取状态码和状态文本
                const {status,statusText} = res;
                return Promise.reject({status,statusText});
            }
            
        }
    })
    .catch(async (error) => {
        // 如果最大重试次数小于等于0，说明已经达到最大重试次数
        if (maxRetries <= 0) {
            return Promise.reject(error);
        }else {
            // 延迟一段时间
            sleep(delay);
            // 递归调用retryRequest函数，重试请求，同时更新最大重试次数
            return retryRequest(url,{delay,maxRetries:maxRetries - 1},requestOptions);
        }
    })
};